home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / OldSrc / CH3 / SRC / CURVETXT.FRM < prev    next >
Text File  |  1996-04-19  |  10KB  |  291 lines

  1. VERSION 4.00
  2. Begin VB.Form CurveTxtForm 
  3.    AutoRedraw      =   -1  'True
  4.    BackColor       =   &H00FFFFFF&
  5.    Caption         =   "CurveTxt"
  6.    ClientHeight    =   5325
  7.    ClientLeft      =   1815
  8.    ClientTop       =   1155
  9.    ClientWidth     =   5715
  10.    Height          =   6015
  11.    Left            =   1755
  12.    LinkTopic       =   "Form1"
  13.    ScaleHeight     =   266.25
  14.    ScaleMode       =   2  'Point
  15.    ScaleWidth      =   285.75
  16.    Top             =   525
  17.    Width           =   5835
  18.    Begin VB.Menu mnuFile 
  19.       Caption         =   "&File"
  20.       Begin VB.Menu mnuFileExit 
  21.          Caption         =   "E&xit"
  22.       End
  23.    End
  24. End
  25. Attribute VB_Name = "CurveTxtForm"
  26. Attribute VB_Creatable = False
  27. Attribute VB_Exposed = False
  28. Option Explicit
  29.  
  30. Const PI = 3.14159
  31. Const PI_OVER_2 = PI / 2
  32.  
  33. ' ***********************************************
  34. ' Draw a text string along a path specified by a
  35. ' series of points (ptx(i), pty(i)). The text is
  36. ' placed above the curve if parameter above is
  37. ' true. The font uses the given font metrics.
  38. ' ***********************************************
  39. Sub CurveText(txt As String, numpts As Integer, ptx() As Single, pty() As Single, above As Boolean, nHeight As Long, nWidth As Long, fnWeight As Long, fbItalic As Long, fbUnderline As Long, fbStrikeOut As Long, fbCharSet As Long, fbOutputPrecision As Long, fbClipPrecision As Long, fbQuality As Long, fbPitchAndFamily As Long, lpszFace As String)
  40. Dim newfont As Long
  41. Dim oldfont As Long
  42. Dim theta As Single
  43. Dim escapement As Long
  44. Dim ch As String
  45. Dim chnum As Integer
  46. Dim needed As Single
  47. Dim avail As Single
  48. Dim newavail As Single
  49. Dim pt As Integer
  50. Dim x1 As Single
  51. Dim y1 As Single
  52. Dim x2 As Single
  53. Dim y2 As Single
  54. Dim dx As Single
  55. Dim dy As Single
  56.  
  57.     avail = 0
  58.     chnum = 1
  59.     
  60.     x1 = ptx(1)
  61.     y1 = pty(1)
  62.     For pt = 2 To numpts
  63.         ' See how long the new segment is.
  64.         x2 = ptx(pt)
  65.         y2 = pty(pt)
  66.         dx = x2 - x1
  67.         dy = y2 - y1
  68.         newavail = Sqr(dx * dx + dy * dy)
  69.         avail = avail + newavail
  70.         
  71.         ' Create a font along the segment.
  72.         If dx > -0.1 And dx < 0.1 Then
  73.             If dy > 0 Then
  74.                 theta = PI_OVER_2
  75.             Else
  76.                 theta = -PI_OVER_2
  77.             End If
  78.         Else
  79.             theta = Atn(dy / dx)
  80.             If dx < 0 Then theta = theta - PI
  81.         End If
  82.         escapement = -theta * 180# / PI * 10#
  83.         If escapement = 0 Then escapement = 3600
  84.         newfont = CreateFont(nHeight, nWidth, escapement, 0, fnWeight, fbItalic, fbUnderline, fbStrikeOut, fbCharSet, fbOutputPrecision, fbClipPrecision, fbQuality, fbPitchAndFamily, lpszFace)
  85.         oldfont = SelectObject(hdc, newfont)
  86.     
  87.         ' Output characters until no more fit.
  88.         Do
  89.             ' See how big the next character is.
  90.             ' (Add a little to prevent characters
  91.             ' from becoming too close together.)
  92.             ch = Mid$(txt, chnum, 1)
  93.             needed = TextWidth(ch) * 1.2
  94.             
  95.             ' If it's too big, get another segment.
  96.             If needed > avail Then Exit Do
  97.             
  98.             ' See where the character belongs
  99.             ' along the segment.
  100.             CurrentX = x2 - dx / newavail * avail
  101.             CurrentY = y2 - dy / newavail * avail
  102.             If above Then
  103.                 ' Place text above the segment.
  104.                 CurrentX = CurrentX + dy * nHeight / newavail
  105.                 CurrentY = CurrentY - dx * nHeight / newavail
  106.             End If
  107.             
  108.             ' Display the character.
  109.             Print ch;
  110.             
  111.             ' Move on to the next character.
  112.             avail = avail - needed
  113.             chnum = chnum + 1
  114.             If chnum > Len(txt) Then Exit Do
  115.         Loop
  116.         
  117.         ' Free the font.
  118.         newfont = SelectObject(hdc, oldfont)
  119.         If DeleteObject(newfont) = 0 Then
  120.             Beep
  121.             MsgBox "Error deleting font object.", vbExclamation
  122.         End If
  123.         
  124.         If chnum > Len(txt) Then Exit For
  125.         x1 = x2
  126.         y1 = y2
  127.     Next pt
  128. End Sub
  129.  
  130. ' ***********************************************
  131. ' Draw a text string along a circle centered at
  132. ' (X, Y) with radius R, centered around the angle
  133. ' theta in radians measured counterclockwise from
  134. ' the X axis.
  135. ' ***********************************************
  136. Sub CircleText(txt As String, X As Single, Y As Single, R As Single, ByVal theta As Single, inside As Boolean, nHeight As Long, nWidth As Long, fnWeight As Long, fbItalic As Long, fbUnderline As Long, fbStrikeOut As Long, fbCharSet As Long, fbOutputPrecision As Long, fbClipPrecision As Long, fbQuality As Long, fbPitchAndFamily As Long, lpszFace As String)
  137. Dim newfont As Long
  138. Dim oldfont As Long
  139. Dim escapement As Long
  140. Dim ch As String
  141. Dim i As Integer
  142. Dim wid As Single
  143. Dim R2 As Single
  144.  
  145.     If inside Then
  146.         R2 = R
  147.     Else
  148.         R2 = R + 0.8 * nHeight
  149.     End If
  150.     
  151.     ' See how long the string is.
  152.     newfont = CreateFont(nHeight, nWidth, 3600, 0, fnWeight, fbItalic, fbUnderline, fbStrikeOut, fbCharSet, fbOutputPrecision, fbClipPrecision, fbQuality, fbPitchAndFamily, lpszFace)
  153.     oldfont = SelectObject(hdc, newfont)
  154.     wid = TextWidth(txt)
  155.     newfont = SelectObject(hdc, oldfont)
  156.     If DeleteObject(newfont) = 0 Then
  157.         Beep
  158.         MsgBox "Error deleting font object.", vbExclamation
  159.     End If
  160.  
  161.     ' The minus sign is needed because Sin and Cos
  162.     ' measure angles clockwise while the input
  163.     ' parameter theta is measured counterclockwise.
  164.     theta = -(theta + wid / R / 2)
  165.  
  166.     ' Start printing letters.
  167.     For i = 1 To Len(txt)
  168.         CurrentX = X + R2 * Cos(theta)
  169.         CurrentY = Y + R2 * Sin(theta)
  170.     
  171.         escapement = (-PI_OVER_2 - theta) * 180# / PI * 10#
  172.         If escapement = 0 Then escapement = 3600
  173.         newfont = CreateFont(nHeight, nWidth, escapement, 0, fnWeight, fbItalic, fbUnderline, fbStrikeOut, fbCharSet, fbOutputPrecision, fbClipPrecision, fbQuality, fbPitchAndFamily, lpszFace)
  174.         oldfont = SelectObject(hdc, newfont)
  175.         
  176.         ch = Mid$(txt, i, 1)
  177.         Print ch
  178.         theta = theta + TextWidth(ch) / R
  179.         
  180.         newfont = SelectObject(hdc, oldfont)
  181.         If DeleteObject(newfont) = 0 Then
  182.             Beep
  183.             MsgBox "Error deleting font object.", vbExclamation
  184.         End If
  185.     Next i
  186. End Sub
  187.  
  188. ' ************************************************
  189. ' Draw an assortment of text samples.
  190. ' ************************************************
  191. Sub DrawTheText()
  192. Const NUM_PTS = 22
  193.  
  194. Dim X As Single
  195. Dim Y As Single
  196. Dim R As Single
  197. Dim pt As Long
  198. Dim fnt As String
  199. Dim ang As Single
  200. Dim i As Integer
  201. Dim ptx(1 To NUM_PTS) As Single
  202. Dim pty(1 To NUM_PTS) As Single
  203. Dim dx As Single
  204. Dim dy As Single
  205.  
  206.     Cls
  207.     MousePointer = vbHourglass
  208.     DoEvents
  209.     
  210.     ' *************************
  211.     ' * Text along a polyline *
  212.     ' *************************
  213.     pt = 20
  214.     fnt = "Times New Roman"
  215.     
  216.     ' Build the points in the path.
  217.     dx = ScaleWidth / (NUM_PTS + 1)
  218.     For i = 1 To NUM_PTS
  219.         ptx(i) = i * dx
  220.         pty(i) = 10 + pt + 10 * Sin(3 * i * PI / NUM_PTS)
  221.     Next i
  222.     
  223.     ' Display the path.
  224.     Line (ptx(1), pty(1))-(ptx(2), pty(2))
  225.     For i = 3 To NUM_PTS
  226.         Line -(ptx(i), pty(i))
  227.     Next i
  228.     
  229.     ' Place text along the path.
  230.     CurveText "Text looks best on a fairly smooth curve.", NUM_PTS, ptx, pty, True, pt, 0, 0, False, False, False, DEFAULT_CHARSET, OUT_TT_ONLY_PRECIS, CLIP_LH_ANGLES Or CLIP_DEFAULT_PRECIS, PROOF_QUALITY, TRUETYPE_FONTTYPE, fnt
  231.     CurveText "Text looks best on a fairly smooth curve.", NUM_PTS, ptx, pty, False, pt, 0, 0, False, False, False, DEFAULT_CHARSET, OUT_TT_ONLY_PRECIS, CLIP_LH_ANGLES Or CLIP_DEFAULT_PRECIS, PROOF_QUALITY, TRUETYPE_FONTTYPE, fnt
  232.     
  233.     ' *****************
  234.     ' * Circular text *
  235.     ' *****************
  236.     pt = 20
  237.     R = 90
  238.     X = ScaleWidth / 2
  239.     Y = R + 20 + 2 * pt
  240.     Circle (X, Y), R
  241.     
  242.     ' Text outside the circle.
  243.     ang = PI_OVER_2
  244.     CircleText "Round and round the mulberry bush", X, Y, R, ang, False, pt, 0, 0, False, False, False, DEFAULT_CHARSET, OUT_TT_ONLY_PRECIS, CLIP_LH_ANGLES Or CLIP_DEFAULT_PRECIS, PROOF_QUALITY, TRUETYPE_FONTTYPE, "Times New Roman"
  245.     ang = -PI_OVER_2
  246.     CircleText "The programmer chased the weasel", X, Y, R, ang, False, pt, 0, 0, False, False, False, DEFAULT_CHARSET, OUT_TT_ONLY_PRECIS, CLIP_LH_ANGLES Or CLIP_DEFAULT_PRECIS, PROOF_QUALITY, TRUETYPE_FONTTYPE, "Times New Roman"
  247.  
  248.     ' Text inside the circle.
  249.     pt = 15
  250.     ang = 0
  251.     CircleText "CircleText can display text", X, Y, R, ang, True, pt, 0, 0, False, False, False, DEFAULT_CHARSET, OUT_TT_ONLY_PRECIS, CLIP_LH_ANGLES Or CLIP_DEFAULT_PRECIS, PROOF_QUALITY, TRUETYPE_FONTTYPE, "Courier New"
  252.     ang = PI
  253.     CircleText "Inside or outside the circle", X, Y, R, ang, True, pt, 0, 0, False, False, False, DEFAULT_CHARSET, OUT_TT_ONLY_PRECIS, CLIP_LH_ANGLES Or CLIP_DEFAULT_PRECIS, PROOF_QUALITY, TRUETYPE_FONTTYPE, "Courier New"
  254.  
  255.     ' ************************
  256.     ' * Text along a diamond *
  257.     ' ************************
  258.     pt = 15
  259.     
  260.     ' Build the points in the path.
  261.     dx = 61
  262.     dy = 61
  263.     ptx(1) = X - dx: pty(1) = Y
  264.     ptx(2) = X: pty(2) = Y - dy
  265.     ptx(3) = X + dx: pty(3) = Y
  266.     ptx(4) = X: pty(4) = Y + dy
  267.     ptx(5) = X - dx: pty(5) = Y
  268.     
  269.     ' Display the path.
  270.     Line (ptx(1), pty(1))-(ptx(2), pty(2))
  271.     For i = 3 To 5
  272.         Line -(ptx(i), pty(i))
  273.     Next i
  274.     
  275.     ' Place text along the path.
  276.     CurveText "Sharp corners can cause gaps or overlap when text follows a path.", 5, ptx, pty, True, pt, 0, 0, False, False, False, DEFAULT_CHARSET, OUT_TT_ONLY_PRECIS, CLIP_LH_ANGLES Or CLIP_DEFAULT_PRECIS, PROOF_QUALITY, TRUETYPE_FONTTYPE, fnt
  277.         
  278.     MousePointer = vbDefault
  279. End Sub
  280.  
  281. Private Sub Form_Load()
  282.     DrawTheText
  283. End Sub
  284.  
  285.  
  286. Private Sub mnuFileExit_Click()
  287.     Unload Me
  288. End Sub
  289.  
  290.  
  291.